#include <iostream>
#include <vector>
#include "Thread.hpp"
#include "BlockQueue.hpp"
#include <string>
using std::cout;
using std::endl;
using namespace ThreadModule;
int a = 10;

void Consumer(BlockQueue<int> *&bq)
{
    int cnt  = 0;
    while (true)
    {
        bq->Pop(&cnt);
        cout << "Consumer consum data is :" << cnt << endl;
        // cout << "Consumer: " << bq << endl;
        // sleep(1);
    }
}

void Productor(BlockQueue<int> *&bq)
{
    int cnt = 10;
    while (true)
    {
        bq->Enqueue(cnt);
        cout << "Productor product data is :" << cnt << endl;
        cnt++;
        sleep(1);
    }
}

void StartCom(std::vector<Thread<BlockQueue<int> *>> *&threads, int num, BlockQueue<int> *&bq, func_t<BlockQueue<int> *> func)
{
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread -" + std::to_string(1 + i);
        threads->emplace_back(func, bq, name);
        threads->back().Start();
    }
}

void StartConsumer(std::vector<Thread<BlockQueue<int> *>> *&threads, int num, BlockQueue<int> *&bq)
{
    StartCom(threads, num, bq, Consumer);
}

void StartProductor(std::vector<Thread<BlockQueue<int> *>> *&threads, int num, BlockQueue<int> *&bq)
{
    StartCom(threads, num, bq, Productor);
}

void WaitAllThread(std::vector<Thread<BlockQueue<int> *>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

int main()
{
    BlockQueue<int> *bq = new BlockQueue<int>(10);
    std::vector<Thread<BlockQueue<int> *>> threads;
    std::vector<Thread<BlockQueue<int> *>> *pthreads = &threads;
    StartConsumer(pthreads, 2, bq);
    StartProductor(pthreads, 1, bq);
    WaitAllThread(threads);
    return 0;
}